package com.ruoyi.system.controller;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Validator;

import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.metadata.WriteSheet;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.row.SimpleRowHeightStyleStrategy;
import com.ruoyi.common.exception.ServiceException;
import com.ruoyi.common.utils.DateUtils;
import com.ruoyi.common.utils.RoleUtils;
import com.ruoyi.common.utils.SheetHandler;
import com.ruoyi.common.utils.StringUtils;
import com.ruoyi.common.utils.bean.BeanValidators;
import com.ruoyi.system.domain.*;
import com.ruoyi.system.domain.temple.DirectTemple;
import com.ruoyi.system.service.*;
import com.ruoyi.system.utils.DataByMonth;
import com.ruoyi.system.utils.DataByYear;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import com.ruoyi.common.annotation.Log;
import com.ruoyi.common.core.controller.BaseController;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.enums.BusinessType;
import com.ruoyi.common.utils.poi.ExcelUtil;
import org.springframework.web.multipart.MultipartFile;

/**
 * 直接费用Controller
 *
 * @author xuliang
 * @date 2024-03-29
 */
@RestController
@RequestMapping("/system/direct")
@Slf4j
public class DirectController extends BaseController
{
    @Autowired
    private IProjectInfoService projectInfoService;
    @Autowired
    private IProcurementDetailService procurementDetailService;
    @Autowired
    private ILaborService laborService;
    @Autowired
    private IDirectService directService;
    @Autowired
    private IIndirectService indirectService;
    @Autowired
    private IOutputService outputService;
    @Autowired
    protected Validator validator;

    /**
     * 查询直接费用列表
     */
    @PreAuthorize("@ss.hasPermi('system:direct:list')")
    @GetMapping("/list")
    public Map<String,Object> list(Direct direct)
    {

        if(!RoleUtils.hasPermission(projectInfoService.getRoleIdsByUserId(getUserId()))){
            direct.setProjectCode(projectInfoService.getProjectCodeByUserId(getUserId()));
        }else {
            direct.setProjectCode(null);
        }

        startPage();

        List<Direct> directList = directService.selectDirectList(direct);

        Map<Integer,Map<Integer,List<Direct>>> dividedData = DataByMonth.directByMonth(DataByYear.directByYear(directList));

        List<String> projectCodeList = projectInfoService.getProjectCodes(direct.getAreaId());

        Map<String,Object> dataMap = new HashMap<>();
        dataMap.put("projectCodeList",projectCodeList);
        dataMap.put("dataList",getDataTable(directList));

        return dataMap;
    }


    /**
     * 获取直接费用详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:direct:query')")
    @GetMapping(value = "/{id}")
    public AjaxResult getInfo(@PathVariable("id") Long id)
    {
        return success(directService.selectDirectById(id));
    }

    /**
     * 新增直接费用
     */
    @PreAuthorize("@ss.hasPermi('system:direct:add')")
    @Log(title = "直接费用", businessType = BusinessType.INSERT)
    @PostMapping
    public AjaxResult add(@RequestBody Direct direct)
    {

        direct.calculateTax();
        direct.setProjectCode(projectInfoService.getProjectCodeByUserId(getUserId()));
        direct.setCreateBy(getUsername());
        direct.setCreateTime(DateUtils.getNowDate());

        direct.setDateNumber(DateUtils.getMonth());
        projectInfoService.updateProjectNumber(DateUtils.getMonth(),direct.getProjectCode());

        return toAjax(directService.insertDirect(direct));
    }

    /**
     * 修改直接费用
     */
    @PreAuthorize("@ss.hasPermi('system:direct:edit')")
    @Log(title = "直接费用", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@RequestBody Direct direct)
    {

        direct.calculateTax();
        direct.setUpdateBy(getUsername());
        direct.setUpdateTime(DateUtils.getNowDate());

        return toAjax(directService.updateDirect(direct));
    }

    /**
     * 删除直接费用
     */
    @PreAuthorize("@ss.hasPermi('system:direct:remove')")
    @Log(title = "直接费用", businessType = BusinessType.DELETE)
	@DeleteMapping("/{ids}")
    public AjaxResult remove(@PathVariable Long[] ids)
    {
        return toAjax(directService.deleteDirectByIds(ids));
    }


    @Log(title = "专业分包导入", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('system:direct:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, @RequestParam("areaId")String areaStr,
                                 @RequestParam("dateNumber")String dateNumber) throws Exception
    {
        log.info("areaId: " + areaStr);
        Integer areaId = Integer.parseInt(areaStr);

        ExcelUtil<Direct> directUtil = new ExcelUtil<Direct>(Direct.class);
        if(file.isEmpty()){
            return error("文件为空");
        }

        InputStream inputStream = file.getInputStream();

        List<Direct> directList = directUtil.importExcel(inputStream,2);

        if (StringUtils.isNull(directList) || directList.size() == 0)
        {
            throw new ServiceException("导入数据不能为空！");
        }

        LocalDate currentDate = LocalDate.now();
        int currentYear = currentDate.getYear();
        int currentMonth = currentDate.getMonthValue();
        String operName = getUsername();
        //
        int successNum = 0;
        int failureNum = 0;
        StringBuilder successMsg = new StringBuilder();
        StringBuilder failureMsg = new StringBuilder();
        int count;
        for (Direct direct : directList)
        {
            direct.setAreaId(areaId);
            direct.setProjectCode(projectInfoService.getProjectCodeByUserId(getUserId()));
            if(direct.getDateNumber() != null){
                String entityDate = direct.getDateNumber();
                LocalDate entityLocalDate = LocalDate.parse(entityDate + "-01"); // 添加一个固定的日期作为日期格式化的补充，这里假设为每月的第一天

                int entityYear = entityLocalDate.getYear();
                int entityMonth = entityLocalDate.getMonthValue();
                if(currentYear == entityYear && currentMonth == entityMonth){
                    direct.setDateNumber(DateUtils.getMonth());
                }
            }else {
                direct.setDateNumber(dateNumber);
                log.info("前端 dateNumber：" + dateNumber);
            }
            try
            {
                // 验证是否存在该条数据
                Direct query = new Direct();
                query.setProjectCode(direct.getProjectCode());
                query.setContractCode(direct.getContractCode());
                query.setDateNumber(direct.getDateNumber());
                query.setSupplier(direct.getSupplier());

                count = directService.countDirectByContractCodeAndNumber(query);

                BeanValidators.validateWithException(validator, direct);
                if(count != 0){
                    direct.setUpdateBy(operName);
                    direct.setUpdateTime(DateUtils.getNowDate());
                    direct.calculateTax();
                    directService.updateDirect(direct);
                    successNum++;
                    successMsg.append("<br/>").append(successNum)
                            .append("、明细 ：").append(direct.getDirectName())
                            .append(" ， 合同编号 ：").append(direct.getContractCode())
                            .append(" 更新成功");
                }else {
                    direct.setCreateBy(operName);
                    direct.setCreateTime(DateUtils.getNowDate());
                    direct.calculateTax();
                    directService.insertDirect(direct);
                    successNum++;
                    successMsg.append("<br/>").append(successNum)
                            .append("、专业分包 ：").append(direct.getDirectName())
                            .append(" ， 合同编号 ：").append(direct.getContractCode())
                            .append(" 导入成功");
                }
            }
            catch (Exception e)
            {
                failureNum++;
                String msg = "<br/>" + failureNum + "、专业分包 ：" + direct.getDirectName() + (" ， 合同编号 ：") + direct.getContractCode()
                        + " 导入失败：";
                failureMsg.append(msg).append(e.getMessage());
                log.error(msg, e);
            }
        }
        if (failureNum > 0)
        {
            failureMsg.insert(0, "部分导入失败！共 " + failureNum + " 条数据格式不正确，错误如下：");
            throw new ServiceException(failureMsg.toString());
        }
        else
        {
            successMsg.insert(0, "数据已全部导入成功！共 " + successNum + " 条，数据如下：");
        }

        inputStream.close();

        return success(successMsg.toString());
    }

    /**
     * @author : xuliang
     * @date   : 2024/4/15
     * @description : 下载模板
     */
    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) throws IOException {

        // 创建 ExcelWriter 对象
        ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream()).relativeHeadRowIndex(2).build();

        // 设置表头样式
        WriteCellStyle headCellStyle = new WriteCellStyle();
        WriteFont headFont = new WriteFont();
        headFont.setFontHeightInPoints((short) 10); // 设置字体大小
        headCellStyle.setWriteFont(headFont);
        headCellStyle.setFillForegroundColor(IndexedColors.GREY_25_PERCENT.getIndex()); // 设置背景颜色
        headCellStyle.setFillPatternType(FillPatternType.SOLID_FOREGROUND);
        //垂直居中,水平居中
        headCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        headCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        headCellStyle.setBorderLeft(BorderStyle.THIN);
        headCellStyle.setBorderTop(BorderStyle.THIN);
        headCellStyle.setBorderRight(BorderStyle.THIN);
        headCellStyle.setBorderBottom(BorderStyle.THIN);
        headCellStyle.setWrapped(true);

        // 创建自定义的内容样式
        WriteCellStyle contentCellStyle = new WriteCellStyle();
        WriteFont contentFont = new WriteFont();
        contentFont.setFontHeightInPoints((short) 10); // 设置字体大小
        contentCellStyle.setWriteFont(contentFont);
        contentCellStyle.setWrapped(true); // 设置文字过长时自动换行
        //垂直居中,水平居中
        contentCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        contentCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);
        contentCellStyle.setBorderLeft(BorderStyle.THIN);
        contentCellStyle.setBorderTop(BorderStyle.THIN);
        contentCellStyle.setBorderRight(BorderStyle.THIN);
        contentCellStyle.setBorderBottom(BorderStyle.THIN);

        // 创建 模板 Excel
        WriteSheet directTemplate = EasyExcel.writerSheet(0,"专业分包")
                .head(DirectTemple.class)
                .registerWriteHandler(new SheetHandler())
                .registerWriteHandler(new HorizontalCellStyleStrategy(headCellStyle,contentCellStyle))
                .registerWriteHandler(new SimpleRowHeightStyleStrategy((short)40,(short)20)) // 简单的行高策略：头行高30，内容行高20
                .build();

        // 创建 模板 数据对象
        List<DirectTemple> directTemplateDataList = new ArrayList<>();
        directTemplateDataList.add(new DirectTemple());

        excelWriter.write(directTemplateDataList, directTemplate);

        excelWriter.finish();
    }

    /**
     * 导出直接费用列表
     */
    @PreAuthorize("@ss.hasPermi('system:direct:export')")
    @Log(title = "直接费用", businessType = BusinessType.EXPORT)
    @PostMapping("/export")
    public void export(HttpServletResponse response, Direct direct)
    {
        List<Direct> list = directService.selectDirectList(direct);
        ExcelUtil<Direct> util = new ExcelUtil<Direct>(Direct.class);
        util.exportExcel(response, list, "直接费用数据");
    }

}
